package com.hzeport.bgs22emduty.inbound.api;

import cn.hutool.core.io.FileUtil;
import com.alibaba.nacos.common.utils.UuidUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzeport.bgs22emduty.config.SystemConfig;
import com.hzeport.bgs22emduty.config.exception.HdcException;
import com.hzeport.bgs22emduty.config.login.LoginCompoentService;
import com.hzeport.bgs22emduty.config.login.UserInfoDetailVO;
import com.hzeport.bgs22emduty.config.systemLog.OperLog;
import com.hzeport.bgs22emduty.dto.DutyScheduleInfoDTO;
import com.hzeport.bgs22emduty.dto.DutyScheduleInfoSaveVO;
import com.hzeport.bgs22emduty.dto.MoneylistDTO;
import com.hzeport.bgs22emduty.dto.scheduleInfo.DutyScheduleInfoDownloadDTO;
import com.hzeport.bgs22emduty.entity.DutyScheduleInfo;
import com.hzeport.bgs22emduty.entity.ExportLog;
import com.hzeport.bgs22emduty.entity.WarningLog;
import com.hzeport.bgs22emduty.enums.ActionTypeEnum;
import com.hzeport.bgs22emduty.enums.OperateTypeEnum;
import com.hzeport.bgs22emduty.outbound.*;
import com.hzeport.bgs22emduty.service.BaseDeptInfoService;
import com.hzeport.bgs22emduty.service.DutyScheduleInfoService;
import com.hzeport.bgs22emduty.service.WarningLogService;
import com.hzeport.bgs22emduty.util.ExcelUtil;
import com.hzeport.bgs22emduty.util.ExcelUtils;
import com.hzeport.bgs22emduty.util.GuavacacheUtils;
import com.hzeport.bgs22emduty.vo.DutyScheduleInfoDetailVO;
import com.hzeport.bgs22emduty.vo.dutyScheduleInfo.DutyScheduleInfoListVO;
import com.hzeport.bgs22emduty.vo.dutyScheduleInfo.DutyScheduleInfoVO;
import com.hzeport.bgs22emduty.vo.dutyScheduleInfo.DutyScheduleinfoMoneyVO;
import com.hzeport.bgs22emduty.vo.dutydignInfo.DutyScheduleExcleVO;
import com.hzeport.bgs22emduty.common.base.BaseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

/**
 * ${comments}
 *
 * @author code generator
 * @date 2022-12-02 11:21:59
 */
@RestController
@AllArgsConstructor
@RequestMapping("/dutyscheduleinfo")
@Api(value = "dutyscheduleinfo", tags = "人员排班管理")
@Slf4j
public class DutyScheduleInfoController {

    private final DutyScheduleInfoService dutyScheduleInfoService;
    
    private final DutyScheduleInfoRepository dutyScheduleInfoRepository;

    private final BaseDeptInfoRepository baseDeptInfoRepository;
    private final BaseDeptInfoService baseDeptInfoService;

    private final BasePersonInfoRepository basePersonInfoRepository;

    private final DutyScheduleSetCustomRepository dutyScheduleSetCustomRepository;

    private final ParamDutyRepository paramDutyRepository;

    private final GuavacacheUtils guavacacheUtils;
    @Resource
    private LoginCompoentService loginCompoentService;

    @Resource
    private ExportLogRepository exportLogRepository;

    @Resource
    private SystemConfig systemConfig;
    @Resource
    private  WarningLogRepository warningLogRepository;

    @Resource
    private DutySignInfoRepository dutySignInfoRepository;

    @Resource
    private WarningLogService warningLogService;

    @ApiOperation(value = "分页查询", notes = "分页查询")
    @PostMapping("/getDutyScheduleInfoPage")
    public BaseResult getDutyScheduleInfoPage(@RequestBody DutyScheduleInfoListVO dutyScheduleInfo) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        return BaseResult.ok(dutyScheduleInfoService.getDutyScheduleInfoPage(dutyScheduleInfo,userInfoDetailVO));
    }

    @ApiOperation(value = "值班查询", notes = "值班查询")
    @PostMapping("/getlistPage")
    public BaseResult<Page<DutyScheduleInfoVO>> getlistPage(@RequestBody DutyScheduleInfoDTO dutyScheduleInfo) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        // 超高频次访问报警
        warningLogService.accessCntValidate("/dutyscheduleinfo/getlistPage", userInfoDetailVO.getPersonId());
        return dutyScheduleInfoService.getlistPage(dutyScheduleInfo,userInfoDetailVO);
    }

    @ApiOperation(value = "值班补贴查询", notes = "值班补贴查询")
    @PostMapping("/moneylist")
    public BaseResult<Page<DutyScheduleinfoMoneyVO>>  moneylist(@RequestBody MoneylistDTO moneylistDTO){
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        return dutyScheduleInfoService.moneylist(moneylistDTO,userInfoDetailVO);
    }

    @ApiOperation(value = "值班补贴导出", notes = "值班补贴导出")
    @PostMapping("/exportmoney")
    public String exportmoney(@RequestBody MoneylistDTO moneylistDTO) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        return dutyScheduleInfoService.exportmoney(moneylistDTO,userInfoDetailVO);
    }

    @ApiOperation(value = "值班补贴导出数据-根据文件名获取文件")
    @RequestMapping(value = "exportsByName",method = RequestMethod.GET)
    public void exportsByName(@RequestParam("name")String name,HttpServletResponse response) throws Exception {
        String modelPath=systemConfig.getFileUrl()+File.separator+name;
        File file = FileUtils.getFile(modelPath);
        String filename="值班补贴.xlsx";
        if(!file.exists()){
            return;
        }
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
            OutputStream out = response.getOutputStream();
            //读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = fis.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            out.flush();
        } catch (Exception e) {
            log.error("获取excel异常");
        }finally {
            try{
                if(fis!=null){
                    fis.close();
                }
            }catch (Exception e){
                log.error("关闭失败");
            }
        }
        return ;
    }

    @ApiOperation(value = "获取值班导入模板")
    @RequestMapping(value = "getInfoImportModel",method = RequestMethod.GET)
    public void getInfoImportModel(HttpServletResponse response) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        String modelPath;
        if (userInfoDetailVO.getRole().contains("ZGGLY")) {
            modelPath = systemConfig.getWordFileUrl() + File.separator + "总署人员排班导入模板.xlsx";
        }else {
            modelPath = systemConfig.getWordFileUrl() + File.separator + "人员排班导入模板.xlsx";
        }
        File file = FileUtils.getFile(modelPath);
        String filename="人员排班导入模板.xls";
        if(!file.exists()){
            log.error("文件不存在|"+modelPath);
            return;
        }
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);

            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
            OutputStream out = response.getOutputStream();
            //读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = fis.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            out.flush();
        } catch (Exception e) {
            log.error("获取excel异常",e);
        }finally {
            try{
                if(fis!=null){
                    fis.close();
                }
            }catch (Exception e){
                log.error("关闭失败",e);
            }
        }
        return ;
    }

    @ApiOperation(value = "导入")
    @PostMapping(value = "imports")
    @OperLog( systemName = "RYPB", description = "PBDR")
    public void imports(@RequestPart List<MultipartFile> file,  HttpServletRequest request , HttpServletResponse response){
        UserInfoDetailVO userInfoDetail=loginCompoentService.getUserInfo();
        if (userInfoDetail.getRole().contains("ZGGLY")) {
            doZGimport(file,userInfoDetail,request , response);
        }else {
           doImport(file,userInfoDetail,request , response);
        }

    }

    private BaseResult doZGimport(List<MultipartFile> file, UserInfoDetailVO userInfoDetail, HttpServletRequest request,HttpServletResponse response) {
        String originalFilename = file.get(0).getOriginalFilename();
        String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
        if(!".xls".equalsIgnoreCase(fileType) && !".xlsx".equalsIgnoreCase(fileType) ){
            return  new BaseResult(2,"请导入excel文件",null);
        }
        String customCode=userInfoDetail.getCustomscode();
        if (com.alibaba.excel.util.StringUtils.isEmpty(customCode)){
            return  new BaseResult(2,"当前登陆人未配置三统一工号",null);
        }
        DutyScheduleInfo dutyScheduleExcelVO = new DutyScheduleInfo();
        String fileName = ExcelUtils.importZGSchedulePerson(file.get(0), dutyScheduleExcelVO,
                dutyScheduleInfoRepository,baseDeptInfoRepository,basePersonInfoRepository,systemConfig.getFileUrl(),userInfoDetail,baseDeptInfoService,paramDutyRepository,dutySignInfoRepository,response,dutyScheduleSetCustomRepository,guavacacheUtils);
        if(com.alibaba.druid.util.StringUtils.isEmpty(fileName)){
            return  BaseResult.ok("导入成功");
        }else {
            if (!fileName.contains("xls")){
                return  new BaseResult(2,"导入失败,原因为："+fileName,null);
            }else {
                return BaseResult.failed(fileName, "导入失败");
            }
        }
    }

    private BaseResult doImport(List<MultipartFile> file,  UserInfoDetailVO userInfoDetail, HttpServletRequest request,HttpServletResponse response) {
        String originalFilename = file.get(0).getOriginalFilename();
//        String month="2023-11-11";
//        String[] tempArray = month.split("-");
//        Long yearLong = Long.valueOf(tempArray[0]);
//        Long monthLong = Long.valueOf(tempArray[1]);
//        DutyScheduleSetCustom dutyScheduleSetCustom = dutyScheduleSetCustomRepository.getOne(new LambdaQueryWrapper<DutyScheduleSetCustom>()
//                .le(DutyScheduleSetCustom::getSYearStart, yearLong)
//                .ge(DutyScheduleSetCustom::getSYearEnd, yearLong)
//                .le(DutyScheduleSetCustom::getSMonthStart, monthLong)
//                .ge(DutyScheduleSetCustom::getSMonthEnd, monthLong)
//                .eq(DutyScheduleSetCustom::getCustomId, userInfoDetail.getCustomscode())
//                .eq(DutyScheduleSetCustom::getSStatus, SStatusEnum.TYPE_SUBMIT.getValue()));
//        if (dutyScheduleSetCustom == null) {
//            return  new BaseResult(2,"未初始化此关区此年份的排班规划！",null);
//        }
        String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
        if(!".xls".equalsIgnoreCase(fileType) && !".xlsx".equalsIgnoreCase(fileType) ){
            return  new BaseResult(2,"请导入excel文件",null);
        }
        String customCode=userInfoDetail.getCustomscode();
        if (com.alibaba.excel.util.StringUtils.isEmpty(customCode)){
            return  new BaseResult(2,"当前登陆人未配置三统一工号",null);
        }
        DutyScheduleInfo dutyScheduleExcelVO = new DutyScheduleInfo();
        String fileName = ExcelUtils.importSchedulePerson(file.get(0), dutyScheduleExcelVO,  dutyScheduleInfoRepository,baseDeptInfoRepository,basePersonInfoRepository,systemConfig.getFileUrl(),userInfoDetail,baseDeptInfoService,paramDutyRepository,dutyScheduleInfoRepository,dutySignInfoRepository,response,dutyScheduleSetCustomRepository,guavacacheUtils);
        if(com.alibaba.druid.util.StringUtils.isEmpty(fileName)){
            return  BaseResult.ok("导入成功");
        }else {
            if (!fileName.contains("xls")){
                return  new BaseResult(2,"导入失败,原因为："+fileName,null);
            }else {
                return BaseResult.failed(fileName, "导入失败");
            }
        }
    }


    /**
     * 通过id查询${comments}
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/detail")
    public BaseResult getById(@RequestParam("id") String id) {
       DutyScheduleInfo dutyScheduleInfo= dutyScheduleInfoService.getById(id);
        DutyScheduleInfoDetailVO dutyScheduleInfoDetailVO=new DutyScheduleInfoDetailVO();
        BeanUtils.copyProperties(dutyScheduleInfo,dutyScheduleInfoDetailVO);
        if (!StringUtils.isEmpty(dutyScheduleInfo.getDDept())){
            List<String> depts=baseDeptInfoService.getParentIds(dutyScheduleInfo.getDDept(),dutyScheduleInfo.getCustomId());
            Collections.reverse(depts);
            dutyScheduleInfoDetailVO.setDDept(depts);
            UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
            if (userInfoDetailVO.getRole().contains("ZGGLY")){
                dutyScheduleInfoDetailVO.setDDept(depts.subList(1,depts.size()));
            }
        }
        String personName;
        String userNo=dutyScheduleInfo.getDUserno()!=null?"(" + dutyScheduleInfo.getDUserno()+ ")":"";
        String deptName=dutyScheduleInfo.getDDeptname()!=null?"(" +dutyScheduleInfo.getDDeptname()+ ")":"";
        if (!dutyScheduleInfo.getDUsername().contains("(")) {
            personName = dutyScheduleInfo.getDUsername() != null ? dutyScheduleInfo.getDUsername() : "";
            dutyScheduleInfoDetailVO.setFullPersonNameWithPersonId(personName+ userNo + deptName);
        }else {
            personName=dutyScheduleInfo.getDUsername();
            dutyScheduleInfoDetailVO.setFullPersonNameWithPersonId(personName + deptName);
        }
        return BaseResult.ok(dutyScheduleInfoDetailVO);
    }

//    /**
//     * 新增${comments}
//     * @param dutyScheduleInfo ${comments}
//     * @return R
//     */
    @ApiOperation(value = "新增${comments}", notes = "新增${comments}")
    @PostMapping("save")
    @OperLog(systemName = "YJZB",description = "XQXZ")
    public BaseResult saveInfo(@RequestBody DutyScheduleInfoSaveVO dutyScheduleInfoSaveVO) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        return BaseResult.ok(dutyScheduleInfoService.saveInfo(dutyScheduleInfoSaveVO,userInfoDetailVO));
    }
//
//    @ApiOperation(value = "新增${comments}", notes = "新增${comments}")
//    @PostMapping("save")
//    public BaseResult saveInfo(@RequestBody DudyScheduleSaveVO dudyScheduleSaveVO) throws Exception {
//        return BaseResult.ok(dutyScheduleInfoService.saveInfo(dudyScheduleSaveVO));
//    }

    @ApiOperation(
            value = "word模板导出-获取文件名${comments}",
            notes = "word模板导出-获取文件名$${comments}"
    )
    @PostMapping({"getWordName"})
    @ResponseBody
    public BaseResult downloadWordGetWordName(@RequestBody DutyScheduleInfoDownloadDTO dutyScheduleInfoDownloadDTO) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        String fileUrl = dutyScheduleInfoService.downloadWord(dutyScheduleInfoDownloadDTO.getYearAndMonth(), dutyScheduleInfoDownloadDTO.getType(),userInfoDetailVO);
        if (StringUtils.isBlank(fileUrl)){
            return BaseResult.failed("未有符合条件的数据");
        }
        return BaseResult.ok(fileUrl);
    }
    @ApiOperation(
            value = "word模板导出${comments}",
            notes = "word模板导出${comments}"
    )
    @RequestMapping({"downloadWord"})
    @ResponseBody
    public void downloadWord(HttpServletResponse response, String fileUrl) throws Exception {
        File file = FileUtil.newFile(fileUrl);
        String name = file.getName();
//        InputStream fis = new BufferedInputStream(new FileInputStream(fileUrl));
//        byte[] buffer = new byte[fis.available()];
//        fis.read(buffer);
//        fis.close();
        response.reset();
        response.setContentType("application/octet-stream;charset=UTF-8");
        String fileName = new String(name.getBytes("gb2312"), "iso8859-1");

        response.setHeader("Content-disposition", "attachment;filename=" + httpMatches(fileName));

//        ServletOutputStream outputStream = response.getOutputStream();
//        outputStream.write(buffer);
//        outputStream.flush();
//        outputStream.close();

        try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))){
            IOUtils.copy(inputStream, response.getOutputStream());
            response.flushBuffer();
        }catch (IOException e) {
            log.info("文件转pdf失败: ", e);
        }
    }

    private String httpMatches(String fileName){
        if (Pattern.matches("[0-9A-Za-z\u4e00-\u9fa5]+",fileName)){
            return fileName;
        }else {
            return "文件名不安全";
        }
    }

//    @ApiOperation(value = "测试", notes = "测试")
//    @RequestMapping("test")
//    public void test(HttpServletResponse response,@RequestParam String yearAndMonth, @RequestParam String type ) throws IOException {
//        List<DutyScheduleExcleVO> dutyScheduleExcleVOS = dutyScheduleInfoService.downloadExcel(yearAndMonth, type);
//        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
//        response.setContentType("application/vnd.ms-excel;charset=utf-8");
//        response.setCharacterEncoding("UTF-8");
//        String excelName = URLEncoder.encode("工作日班排班","UTF-8");
//        response.setHeader("Content-disposition","attachment;filename="+excelName+".xlsx");
//        EasyExcel.write(response.getOutputStream(),DutyScheduleExcleVO.class)
//                .sheet("人员排班")
//                .doWrite(dutyScheduleExcleVOS);
//    }

    @ApiOperation(value = "excel导出-获取文件名", notes = "excel导出-获取文件名")
    @PostMapping("/downloadExcle")
    public String downloadExcel(@RequestBody DutyScheduleInfoDownloadDTO dutyScheduleInfoDownloadDTO ) throws Exception {

        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        List<DutyScheduleExcleVO> dutyScheduleExcleVOS = dutyScheduleInfoService.downloadExcel(dutyScheduleInfoDownloadDTO, userInfoDetailVO);
        String tempFilName= UuidUtils.generateUuid()+".xlsx";
        String fileName=systemConfig.getExcelFileUrl()+ File.separator+tempFilName;
        log.info("PathName:{}"+fileName);
        ExcelUtil.exportGoods(dutyScheduleExcleVOS,fileName);
        return tempFilName;
    }



    @ApiOperation(value = "导出数据表格-根据文件名获取文件", notes = "导出数据表格-根据文件名获取文件")
    @RequestMapping("/downloadExcleData")
    public void downloadExcleData(@RequestParam("name")String name,HttpServletResponse response){
        String modelPath=systemConfig.getExcelFileUrl()+File.separator+name;
        File file = FileUtils.getFile(modelPath);
        if(!file.exists()){
            return;
        }
        FileInputStream fis = null;
        try {
            UserInfoDetailVO user = loginCompoentService.getUserInfo();
            //导出文件需写入日志
            ExportLog exportLog = new ExportLog();
            exportLog.setReqPath("/dutyscheduleinfo/downloadExcleData");
            exportLog.setDataRange(com.alibaba.fastjson.JSONObject.toJSONString(name));
            exportLog.setFileInfo(name);
            exportLog.setOperateType(ActionTypeEnum.DOWN_LOAD.getCode());
            exportLog.setOperatorCode(user.getPersonId());
            exportLogRepository.save(exportLog);
            //判断导出的文件是否超过1g
            long length = file.length();
            long oneGB = 1024L * 1024L * 1024L;
            if (length > oneGB){
                //表示需要写入报警表
                WarningLog warningLog = new WarningLog();
                warningLog.setOperatorCode(user.getPersonId());
                warningLog.setReqPath("/dutyscheduleinfo/downloadExcleData");
                warningLog.setOperateType(OperateTypeEnum.DOWNLOAD_TOO_LARGE_FILE.getCode());//单次下载超过1g;
                warningLogRepository.save(warningLog);
                throw  new HdcException("下载超过1g");
            }
            fis = new FileInputStream(file);
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode("导入模板.xlsx","UTF-8"));
            ServletOutputStream out = response.getOutputStream();
            //读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = fis.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            out.flush();
        } catch (Exception e) {
            log.error("获取excel导入模板异常");
        }finally {
            try{
                if(fis!=null){
                    fis.close();
                }
            }catch (Exception e){
                log.error("关闭失败");
            }
        }
        return ;
    }

    @ApiOperation(value = "excelOrWord判断", notes = "excelOrWord判断")
    @PostMapping("/excelAndWordJudge")
    public String excelAndWordJudge(@RequestParam String type) throws IOException {
        if ("2".equals(type)){
            return "word";
        }
        return "excel";
    }



    /**
     * 通过id删除${comments}
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除${comments}", notes = "通过id删除${comments}")
    @PostMapping("/{id}")
    @OperLog(systemName = "YJZB",description = "XQSC")

    public BaseResult removeById(@PathVariable String id) {
        return BaseResult.ok(dutyScheduleInfoService.removeById(id));
    }


    @ApiOperation(value = "导出", notes = "导出")
    @PostMapping("/exports")
    public BaseResult exports(@RequestBody DutyScheduleInfoListVO dutyScheduleInfo) throws Exception {
        UserInfoDetailVO userInfoDetailVO=loginCompoentService.getUserInfo();
        return BaseResult.ok(dutyScheduleInfoService.getDutyScheduleInfoPage(dutyScheduleInfo,userInfoDetailVO));
    }


}
